/**
 * @class 太阳系数据代理
 * @author DuskyHuang 圣子
 * @description 提供太阳系内相关数据和管理。
*/

import { Color } from 'cc';
import { Proxy, decorators } from 'cfw';
import { UI, View } from 'notifications';
import { Sun } from 'prefabs';
const { singleton } = decorators;

@singleton
export class SolarProxy extends Proxy {

    declare public static readonly instance: SolarProxy;
    private constructor() { super(); }

    public get showSun(): boolean { return this._show_sun; }                    // 显示太阳和光晕
    public get showPlanets(): boolean { return this._show_planets; }            // 显示8大行星（冥王星已被降级为矮行星）
    public get showDwarfs(): boolean { return this._show_dwarfs; }              // 显示矮行星（国际公认共5颗）
    public get showMinors(): boolean { return this._show_minors; }              // 显示小行星（约20颗著名小行星）
    public get showComets(): boolean { return this._show_comets; }              // 显示彗星（前20颗著名彗星）
    public get showBelts(): boolean { return this._show_belts; }                // 显示小行星带（主带+柯伊伯带）
    public get magnifyRatio(): num.pct { return this._magnify_ratio; }          // 放大比例
    public get systemScope(): pow10 { return this._systemScope; }               // 当前恒星系统范围
    public get center(): Sun | null { return this._center; }                    // 当前中心恒星
    public get centerName(): string { return this._center?.config?.name; }      // 当前中心恒星名称

    public getStateByName(name: string): boolean {
        switch (name) {
            case '太阳': return this.showSun;
            case '行星': return this.showPlanets;
            case '矮行星': return this.showDwarfs;
            case '小行星': return this.showMinors;
            case '彗星': return this.showComets;
            case '小行星带': return this.showBelts;
            default: return null;
        }
    }

    public getMagnified(type: into): num.pct {
        return Math.lerp(1, SolarProxy.MaxRatios[type], this._magnify_ratio);
    }

    public static BeltColor = new Color(153, 127, 63, 127);

    public static readonly MaxRatios: Record<orbit | 'star' | 'blackhole', num.ratio> = {
        star: 5e+1,
        blackhole: 5e+1,
        planet: 2e+3,
        dwarf: 1e+4,
        satellite: 1,
        minor: 2e+4,
        comet: 4e+5,
        belts: 2e+6,
        asteroid: 2e+6,
    }

    private _show_planets: boolean = true;
    private _show_dwarfs: boolean = true;
    private _show_minors: boolean = false;
    private _show_comets: boolean = false;
    private _show_belts: boolean = false;
    private _show_sun: boolean = true;
    private _magnify_ratio: num.pct = 0.179;
    private _planets: planet[] = [];
    private _systemScope: pow10 = 0;
    private _center: Sun = null;

    public reloadParams(center: Sun, planets?: planet[], systemScope?: pow10): void {
        this._center = center;
        this._planets.length = this._systemScope = 0;
        if (planets) {
            this._planets.push(...planets);
            this._systemScope = systemScope;
        }
    }

    protected init(): void {
        this.on(PLANETS, (arg: boolean) => this._show_planets = arg);
        this.on(DWARFS, (arg: boolean) => this._show_dwarfs = arg);
        this.on(MINORS, (arg: boolean) => this._show_minors = arg);
        this.on(COMETS, (arg: boolean) => this._show_comets = arg);
        this.on(BELTS, (arg: boolean) => this._show_belts = arg);
        this.on(FLARE, (arg: boolean) => this._show_sun = arg);
        this.on(RATIO, (arg: num.pct) => { this._magnify_ratio = arg; this.notify(View.Scale.RATIO_CHANGE); });
    }
}

const { Solar: { PLANETS, DWARFS, MINORS, COMETS, BELTS, SUN: FLARE, RATIO } } = UI;

export const solar = SolarProxy.instance;